#include "Common.hpp"
#include "InetAddr.hpp"
#include "Log.hpp"
#include "Socket.hpp"
#include <cstdlib>
#include <functional>
#include <future>
#include <iostream>
#include <memory>
#include <sched.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
using namespace SocketModule;
using namespace LogModule;
using service = std::function<void(std::shared_ptr<Socket>& sock, InetAddr& client)>;
class TcpServer {
public:
    TcpServer(uint16_t port) :
    _port(port), _listensockptr(std::make_unique<TcpSocket>()), _isrunning(false) {
        _listensockptr->BuildTcpSocketMethod(_port);
    }
    void Start(service callback) {
        _isrunning = true;
        while (_isrunning) {
            InetAddr client;
            auto sock = _listensockptr->Accept(&client);
            if(sock == nullptr) {
                continue;
            }
            LOG(LogLevel::DEBUG) << "accept success" << client.StringAddr();
            pid_t id = fork();
            if(id > 0) {
                sock->Close();
                pid_t wid = ::waitpid(id, nullptr, 0);
                (void)wid;
            }else if(id < 0) {
                LOG(LogLevel::FATAL) << "fork error";
                exit(FORK_ERR);
            }else {
                _listensockptr->Close();
                if(fork() > 0) {
                    exit(OK);
                }
                callback(sock, client);
                sock->Close();
                exit(OK);
            }
        }
        _isrunning = false;
    }
    ~TcpServer() {}
private:
    uint16_t _port;
    std::unique_ptr<Socket> _listensockptr;
    bool _isrunning;    
};
